API 文件就像程式提供給其他開發者的使用說明書。
ASP.NET Core 10 可以使用 OpenAPI 產生 API 規格文件,再透過 Swagger UI 顯示成容易閱讀的互動頁面。
**打開檔案:**TaskFlow3.Api → Controllers → TasksController.cs
在 GET 全部任務的方法上方加入
找到:
[HttpGet]
public async Task<ActionResult<List<TaskDto>>> GetTasks(
修改為:
[HttpGet]
[EndpointSummary("取得目前使用者的任務")]
[EndpointDescription(
"取得登入者自己的任務,可依完成狀態、關鍵字及排序條件查詢。"
)]
[ProducesResponseType(
typeof(List<TaskDto>),
StatusCodes.Status200OK
)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<List<TaskDto>>> GetTasks(
在 GET 單一任務的方法上方加入
找到 GetTask(int id),讓它的開頭變成:
[HttpGet("{id:int}")]
[EndpointSummary("取得指定任務")]
[EndpointDescription(
"根據任務 ID 取得登入者自己的任務,不會回傳其他使用者的任務。"
)]
[ProducesResponseType(
typeof(TaskDto),
StatusCodes.Status200OK
)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<TaskDto>> GetTask(int id)
在 POST 新增任務的方法上方加入
找到 CreateTask():
[HttpPost]
[EndpointSummary("新增任務")]
[EndpointDescription(
"為目前登入使用者建立一筆新任務,任務名稱必須介於 2 到 100 個字元。"
)]
[ProducesResponseType(
typeof(TaskDto),
StatusCodes.Status201Created
)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<TaskDto>> CreateTask(
[FromBody] CreateTaskDto input)
在 PUT 修改任務的方法上方加入
找到 UpdateTask():
[HttpPut("{id:int}")]
[EndpointSummary("修改任務")]
[EndpointDescription(
"修改登入者自己的任務名稱與完成狀態。"
)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> UpdateTask(
int id,
[FromBody] UpdateTaskDto input)
在 DELETE 刪除任務的方法上方加入
找到 DeleteTask():
[HttpDelete("{id:int}")]
[EndpointSummary("刪除任務")]
[EndpointDescription(
"刪除登入者自己的指定任務,不能刪除其他使用者的任務。"
)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> DeleteTask(int id)
建立新檔案
在 VS Code 左側找到最外層:TaskFlow3
按右鍵選擇「新增檔案」,命名為:API_DOCUMENTATION.md
文件內容
# TaskFlow API 文件
## 1. 專案介紹
TaskFlow 是使用 C#、ASP.NET Core 及 SQLite
開發的任務管理 Web API。
主要功能:
- 註冊與登入
- 新增、查詢、修改與刪除任務
- 依完成狀態篩選任務
- 依任務名稱搜尋
- 依任務 ID 排序
- 限制使用者只能存取自己的任務
## 2. 使用技術
- C#
- .NET 10
- ASP.NET Core Web API
- Entity Framework Core
- SQLite
- ASP.NET Core Identity
- OpenAPI / Swagger UI
- xUnit
- Git
## 3. 本機 API 網址
實際連接埠依 dotnet run 顯示的網址為準。
範例:
http://localhost:5028
Swagger UI:
http://localhost:5028/swagger
OpenAPI JSON:
http://localhost:5028/openapi/v1.json
## 4. 任務 API
| 方法 | 路徑 | 功能 |
|---|---|---|
| GET | /api/tasks | 查詢自己的任務 |
| GET | /api/tasks/{id} | 查詢指定任務 |
| POST | /api/tasks | 新增任務 |
| PUT | /api/tasks/{id} | 修改任務 |
| DELETE | /api/tasks/{id} | 刪除任務 |
上述任務 API 都要求使用者先登入。
## 5. 登入 API
由 ASP.NET Core Identity 提供:
POST /auth/register
POST /auth/login?useCookies=true
登入成功後,可使用同一個 Cookie Session
存取受保護的任務 API。
## 6. 新增任務範例
POST /api/tasks
Request Body:
json
{
"title": "完成 C# 作業"
}
成功後預期回傳 HTTP 201。
Response Body 範例:
json
{
"id": 1,
"title": "完成 C# 作業",
"isCompleted": false
}
## 7. 修改任務範例
PUT /api/tasks/1
Request Body:
json
{
"title": "完成 ASP.NET Core 作業",
"isCompleted": true
}
成功後預期回傳 HTTP 204。
## 8. 查詢參數
GET /api/tasks?completed=false
只查詢未完成任務。
GET /api/tasks?keyword=C%23
搜尋名稱包含 C# 的任務。
GET /api/tasks?sort=desc
依任務 ID 由大到小排序。
參數可以組合使用。
## 9. 常見 HTTP 狀態碼
| 狀態碼 | 意義 |
|---|---|
| 200 | 查詢成功 |
| 201 | 新增成功 |
| 204 | 修改或刪除成功 |
| 400 | 請求資料不符合規則 |
| 401 | 尚未通過身分驗證 |
| 404 | 找不到屬於登入者的指定任務 |
| 500 | 伺服器發生未預期錯誤 |
## 10. 資料安全
每筆新任務都有 OwnerIdentityId。
查詢、修改與刪除時,後端會根據已驗證的
登入者 ID 限制可存取的任務。
不同使用者的私人任務不得互相存取。
## 11. 執行專案
在 TaskFlow3.Api 目錄執行:
powershell
dotnet run
在 TaskFlow3 根目錄執行測試:
powershell
dotnet test .\TaskFlow3.Tests\TaskFlow3.Tests.csproj
## 12. 測試結果
測試日期:尚未填寫
測試環境:Windows / .NET 10
新增任務:待測試
查詢任務:待測試
修改任務:待測試
刪除任務:待測試
登入驗證:待測試
使用者資料隔離:待測試
測試完成後再填入實際結果。

啟動 API
在終端機 1:
cd TaskFlow3.Api
dotnet run
設定測試網址
在終端機 2:$base = "http://localhost:5130"
執行:Invoke-RestMethod -Uri "$base/test" -Method Get
登入測試帳號
$login = @{
email = "student@example.com"
password = "DemoOnly_2026!"
} | ConvertTo-Json
再執行:
Invoke-RestMethod `
-Uri "$base/auth/login?useCookies=true" `
-Method Post `
-ContentType "application/json" `
-Body $login `
-SessionVariable aliceSession
新增任務(POST)
在同一個終端機 2 輸入:
$body = @{
title = "Day 28 API 測試"
} | ConvertTo-Json
$created = Invoke-RestMethod `
-Uri "$base/api/tasks" `
-Method Post `
-ContentType "application/json" `
-Body $body `
-WebSession $aliceSession
$created

查詢任務(GET)
輸入:
Invoke-RestMethod `
-Uri "$base/api/tasks" `
-Method Get `
-WebSession $aliceSession
測試查詢單一任務:
Invoke-RestMethod `
-Uri "$base/api/tasks/$($created.id)" `
-Method Get `
-WebSession $aliceSession

修改任務(PUT)
先建立修改資料:
$updateBody = @{
title = "Day 28 測試已完成"
isCompleted = $true
} | ConvertTo-Json
接著執行:
Invoke-RestMethod `
-Uri "$base/api/tasks/$($created.id)" `
-Method Put `
-ContentType "application/json" `
-Body $updateBody `
-WebSession $aliceSession
再使用 GET 確認:
Invoke-RestMethod `
-Uri "$base/api/tasks/$($created.id)" `
-WebSession $aliceSession
測試搜尋與篩選
查詢已完成的任務:
Invoke-RestMethod `
-Uri "$base/api/tasks?completed=true" `
-WebSession $aliceSession
查詢包含 Day 的任務:
Invoke-RestMethod `
-Uri "$base/api/tasks?keyword=Day" `
-WebSession $aliceSession
依任務 ID 降冪排序:
Invoke-RestMethod `
-Uri "$base/api/tasks?sort=desc" `
-WebSession $aliceSession
刪除任務(DELETE)
最後刪除剛剛新增的測試任務:
Invoke-RestMethod `
-Uri "$base/api/tasks/$($created.id)" `
-Method Delete `
-WebSession $aliceSession
沒有登入就查詢任務
try {
Invoke-RestMethod `
-Uri "$base/api/tasks" `
-Method Get `
-ErrorAction Stop
}
catch {
Write-Host "HTTP 狀態碼:" ([int]$_.Exception.Response.StatusCode)
}

任務名稱太短
輸入:
$invalidBody = @{
title = "A"
} | ConvertTo-Json
try {
Invoke-RestMethod `
-Uri "$base/api/tasks" `
-Method Post `
-ContentType "application/json" `
-Body $invalidBody `
-WebSession $aliceSession `
-ErrorAction Stop
}
catch {
Write-Host "HTTP 狀態碼:" ([int]$_.Exception.Response.StatusCode)
}

使用不存在的任務 ID
try {
Invoke-RestMethod `
-Uri "$base/api/tasks/99999999" `
-Method Get `
-WebSession $aliceSession `
-ErrorAction Stop
}
catch {
Write-Host "HTTP 狀態碼:" ([int]$_.Exception.Response.StatusCode)
}
